package tools;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Arrow extends Path2D.Double {
	Ellipse2D nullCircle = new Ellipse2D.Double();
	/**
	 * Sets the arrow values
	 * @param begin	the origin point of the arrow
	 * @param end the end point of the arrow
	 * @param width	the half width of the arrow tip 
	 * @param height the height of the arrow tip
	 */
	public void setArrow(Point2D begin, Point2D end, double width, double height) {
		this.reset();
		double bay = end.getY()-begin.getY(), bax = end.getX()-begin.getX();
		double baNorm = Math.sqrt(bay*bay+bax*bax);

		if (java.lang.Double.compare(baNorm, 0)==0) {
			this.nullCircle.setFrameFromCenter(end.getX(), end.getY(), end.getX()+width, end.getY()+width);
			this.append(nullCircle, false);
			this.nullCircle.setFrameFromCenter(end.getX(), end.getY(), end.getX()-0.001, end.getY()-0.001);
			this.append(nullCircle, false);
//			this.moveTo(end.getX()+width*Math.cos(Math.toRadians(350)), end.getY());
//			new Ellipse2D.Double().get
//
//			for (int i = 0; i<36; i++) {
//				this.lineTo(end.getX()+width*Math.cos(Math.toRadians(i*10.)), end.getY()+width*Math.sin(Math.toRadians(i*10.)));
//			}
//			this.closePath();
//			this.moveTo(end.getX(), end.getY());
//			for (int i = 0; i<36; i++) {
//				this.lineTo(end.getX()+Math.cos(Math.toRadians(i*10.)), end.getY()+Math.sin(Math.toRadians(i*10.)));
//			}
//			this.closePath();
		} else {
			
			bay /= baNorm;
			bax /= baNorm;
			
			double x = -(bay), y = (bax);

			x *= width;
			y *= width;
			
			bay *= height;
			bax *= height;
//			System.out.println(bay);
			this.moveTo(end.getX()-bax, end.getY()-bay);
			this.lineTo(end.getX()-bax+x, end.getY()-bay+y);
			this.lineTo(end.getX(), end.getY());
			this.lineTo(end.getX()-bax-x, end.getY()-bay-y);
			this.lineTo(end.getX()-bax, end.getY()-bay);
			this.closePath();
//			this.moveTo(end.getX(), end.getY());
			this.lineTo(begin.getX(), begin.getY());
		}
	}
	public static void main(String[] args) {
		JFrame ff = new JFrame();
		ff.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Point2D a = new Point2D.Double(100,100), b = new Point2D.Double(500,300);
		
		double arrowWidth = 10, arrowHeight = 40;
		
		final Arrow arrw = new Arrow();
		arrw.setArrow(a, b, arrowWidth, arrowHeight);
		
		JComponent canvas = new JComponent() {
			{setPreferredSize(new Dimension(800,600));}
			@Override
			public void paint(Graphics g) {
				Graphics2D g2 = (Graphics2D)g;

				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			    g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
			    g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
			    for (int i = 0; i<8; i++) {
				    Point2D p = new Point2D.Double(1,0);
				    AffineTransform rot = AffineTransform.getRotateInstance(Math.PI/4*i);
				    p = rot.transform(p, p);
				    arrw.setArrow(new Point2D.Double(400,300), new Point2D.Double(p.getX()*100+400,p.getY()*100+300), 5, 20);
				    g2.setColor(Color.red);
					g2.fill(arrw);
					g2.setColor(Color.black);
					g2.draw(arrw);
			    }
				super.paint(g);
			}
		};
		
		ff.add(canvas);
		ff.pack();
		ff.setVisible(true);
	}

}
